/*
 * DoubleWord class is composed of 2 words
 * */

package cpu.datatypes;

public class DoubleWord {
	public Word wordHigh = new Word( );
	public Word wordLow = new Word( );
	
	// Default Constructor
	public DoubleWord( ) {
		wordHigh = new Word( );
		wordLow = new Word( );
	}
	// Copy Constructor
	public DoubleWord( DoubleWord dword ) {
		wordHigh = new Word( dword.wordHigh );
		wordLow = new Word( dword.wordLow );
	}
	
	public Word element( int i ) {
		if( i == 0 ) 
			return wordLow;	// 0 : little endian
		return wordHigh;
	}
	public Bit bit( int i ) {
		assert( i >= 0 && i < 32 );
		
		if( i >= 0 && i <= 15  )
			return wordLow.bit( i );	// 0 : little endian
		return wordHigh.bit( i - 16 );
	}
	public int toJavaInt( ) {
		int accumulator = 0;

		for( int i = 0; i < 16; i++ ) {
			if( wordLow.bit( i ).value )
				accumulator += java.lang.Math.pow( 2, i );
		}
		for( int i = 0; i < 16; i++ ) {
			if( wordHigh.bit( i ).value )
				accumulator += java.lang.Math.pow( 2, i + 16 );
		}
		
		return accumulator;
	}
	public boolean fromJavaInt( int value ) {
		// note return value is overflow
		int accumulator = value;
		
		if( value < 0 ) {
			accumulator = -accumulator;
			wordHigh.bit( 0 ).value = true;				
		} else {
			wordHigh.bit( 0 ).value = false;
		}
		
		for( int i = 15; i >= 0; i-- ) {
			if( accumulator / java.lang.Math.pow( 2, i + 16 ) >= 1 ) {
				wordHigh.bit( i ).value = true;
				accumulator -= java.lang.Math.pow( 2, i + 16 );
			} else {
				wordHigh.bit( i ).value = false;
			}
		}
		for( int i = 15; i >= 0; i-- ) {
			if( accumulator / java.lang.Math.pow( 2, i ) >= 1 ) {
				wordLow.bit( i ).value = true;
				accumulator -= java.lang.Math.pow( 2, i );
			} else {
				wordLow.bit( i ).value = false;
			}
		}

		if( accumulator != 0 ) 
			return true;		// overflow
		return false;			// no overflow			
	}
	public long toJavaLong( ) {
		long accumulator = 0;
		for( int i = 0; i < 16; i++ ) {
			if( wordLow.bit( i ).value )
				accumulator += java.lang.Math.pow( 2, i );
		}
		for( int i = 0; i < 16; i++ ) {
			if( wordHigh.bit( i ).value )
				accumulator += java.lang.Math.pow( 2, i + 16 );
		}
		return accumulator;
	}
	public boolean fromJavaLong( long value ) {
		// note return value is overflow
		long accumulator = value;
		for( int i = 15; i >= 0; i-- ) {
			if( accumulator / java.lang.Math.pow( 2, i + 16 ) >= 1 ) {
				wordHigh.bit( i ).value = true;
				accumulator -= java.lang.Math.pow( 2, i + 16 );
			} else {
				wordHigh.bit( i ).value = false;
			}
		}
		for( int i = 15; i >= 0; i-- ) {
			if( accumulator / java.lang.Math.pow( 2, i ) >= 1 ) {
				wordLow.bit( i ).value = true;
				accumulator -= java.lang.Math.pow( 2, i );
			} else {
				wordLow.bit( i ).value = false;
			}
		}
		if( accumulator != 0 ) 
			return true;		// overflow
		return false;			// no overflow
	}
}
